package configmap

import (
	"encoding/json"
	"errors"
	"io/ioutil"

	"k8s.io/klog/v2"
)

// Parse is a method to parse the configmap.
func Parse(path string,
	devices map[string]*DeviceInstance,
	dms map[string]DeviceModel,
	protocols map[string]Protocol) error {
	var deviceProfile DeviceProfile
	jsonFile, err := ioutil.ReadFile(path)
	if err != nil {
		return errors.New(".json not found," + err.Error())
	}
	//Parse the JSON file and convert it into the data structure of DeviceProfile
	if err = json.Unmarshal(jsonFile, &deviceProfile); err != nil {
		return err
	}
	for i := 0; i < len(deviceProfile.DeviceInstances); i++ {
		instance := deviceProfile.DeviceInstances[i]
		j := 0
		for j = 0; j < len(deviceProfile.Protocols); j++ {
			if instance.ProtocolName == deviceProfile.Protocols[j].Name {
				instance.PProtocol = deviceProfile.Protocols[j]
				break
			}
		}
		if j == len(deviceProfile.Protocols) {
			err = errors.New("protocol not found")
			return err
		}
		for k := 0; k < len(instance.PropertyVisitors); k++ {
			modelName := instance.PropertyVisitors[k].ModelName
			propertyName := instance.PropertyVisitors[k].PropertyName
			l := 0
			for l = 0; l < len(deviceProfile.DeviceModels); l++ {
				if modelName == deviceProfile.DeviceModels[l].Name {
					m := 0
					for m = 0; m < len(deviceProfile.DeviceModels[l].Properties); m++ {
						if propertyName == deviceProfile.DeviceModels[l].Properties[m].Name {
							instance.PropertyVisitors[k].PProperty = deviceProfile.DeviceModels[l].Properties[m]
							break
						}
					}
					if m == len(deviceProfile.DeviceModels[l].Properties) {
						err = errors.New("property not found")
						return err
					}
					break
				}
			}
			if l == len(deviceProfile.DeviceModels) {
				err = errors.New("device model not found")
				return err
			}
		}
		for k := 0; k < len(instance.Twins); k++ {
			name := instance.Twins[k].PropertyName
			l := 0
			for l = 0; l < len(instance.PropertyVisitors); l++ {
				if name == instance.PropertyVisitors[l].PropertyName {
					instance.Twins[k].PVisitor = &instance.PropertyVisitors[l]
					break
				}
			}
			if l == len(instance.PropertyVisitors) {
				return errors.New("propertyVisitor not found")
			}
		}
		for k := 0; k < len(instance.Datas.Properties); k++ {
			name := instance.Datas.Properties[k].PropertyName
			l := 0
			for l = 0; l < len(instance.PropertyVisitors); l++ {
				if name == instance.PropertyVisitors[l].PropertyName {
					instance.Datas.Properties[k].PVisitor = &instance.PropertyVisitors[l]
					break
				}
			}
			if l == len(instance.PropertyVisitors) {
				return errors.New("propertyVisitor not found")
			}
		}
		devices[instance.ID] = new(DeviceInstance)
		devices[instance.ID] = &instance
		klog.V(4).Info("Instance: ", instance.ID)
	}
	for i := 0; i < len(deviceProfile.DeviceModels); i++ {
		dms[deviceProfile.DeviceModels[i].Name] = deviceProfile.DeviceModels[i]
	}
	for i := 0; i < len(deviceProfile.Protocols); i++ {
		protocols[deviceProfile.Protocols[i].Name] = deviceProfile.Protocols[i]
	}
	return nil
}
